﻿
using AnesSystem.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using AnesSystem.Services;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Reflection;
using Common;
using AnesSystem.ViewModels;

namespace AnesSystem.Util
{
    public static class ExtensionMethods
    {
        #region Variables

        #endregion

        #region Constructor

        #endregion

        #region Properties

        #endregion

        #region 依赖属性

        #endregion

        #region Event

        #endregion

        #region Private Methods

        #endregion

        #region Public/Protected Methods

        public static void FillData(BsonElement c, object tObj, IEnumerable<PropertyInfo> tPros)
        {
            try
            {
                foreach (var tPro in tPros)
                {
                    string str = c.Name.ToLower();
                    if (str.Equals("_id"))
                    {
                        str = str.Replace("_", "");
                    }
                    if (tPro != null)
                    {
                        if (tPro.PropertyType.FullName.Contains("AnesSystem.Models") && !c.Value.IsBsonArray && !c.Name.ToLower().Equals("tables"))
                        {
                            if (tPro.Name.ToLower().Equals(c.Name.ToLower()))
                            {
                                object obj = Activator.CreateInstance(tPro.PropertyType);
                                if (c.Value.IsBsonDocument)
                                {
                                    foreach (var e in c.Value.ToBsonDocument().Elements)
                                    {
                                        try
                                        {
                                            if (e.Value.IsBsonNull) continue;
                                            FillData(e, obj, obj.GetType().GetProperties());
                                        }
                                        catch (Exception ex)
                                        {
                                            Common.LogHelper.Error("BaseService", ex);
                                        }
                                    }
                                }

                                tPro.SetValue(tObj, obj);
                                break;
                            }
                        }
                        else if (str.Equals(tPro.Name.ToLower()))
                        {

                            if (c.Name.ToLower().Contains("tables"))
                            {
                                BsonValue root = c.Value;
                                Dictionary<string, CommonTableModel> dic = new Dictionary<string, CommonTableModel>();
                                IEnumerable<BsonElement> elements = root.ToBsonDocument().Elements;
                                foreach (var ele in elements)
                                {
                                    if (ele.Value.ToBsonDocument().GetValue("XmlContent").IsBsonNull) continue;
                                    CommonTableModel table = new CommonTableModel()
                                    {
                                        TableName = ele.Name,
                                        XmlContent = ele.Value.ToBsonDocument().GetValue("XmlContent").AsString
                                    };
                                    dic.Add(ele.Name, table);
                                    continue;

                                    string name = ele.Name;
                                    IEnumerable<BsonElement> itemElements = ele.Value.ToBsonDocument().Elements;
                                    List<ClassHelper.CustPropertyInfo> proList = new List<ClassHelper.CustPropertyInfo>();
                                    Dictionary<string, string> values = new Dictionary<string, string>();
                                    foreach (var iEle in itemElements)
                                    {
                                        ClassHelper.CustPropertyInfo pro = new ClassHelper.CustPropertyInfo("System.String", iEle.Name);
                                        proList.Add(pro);
                                        values.Add(iEle.Name, iEle.Value.IsBsonNull ? "" : iEle.Value.AsString);
                                    }
                                    CommonTableModel tableModel = ClassHelper.CreateInstance(name, proList, "AnesSystem.Models.CommonTableModel") as CommonTableModel;
                                    foreach (var pro in proList)
                                    {
                                        tableModel.GetType().GetProperty(pro.PropertyName).SetValue(tableModel, values[pro.PropertyName]);
                                    }
                                    dic.Add(name, tableModel);
                                }
                                if (dic.Count != 0)
                                    tPro.SetValue(tObj, dic);
                                break;
                            }
                            if (c.Value.IsBoolean && tPro.PropertyType == typeof(bool))
                            {
                                tPro.SetValue(tObj, c.Value.AsBoolean);
                                break;
                            }
                            else if (c.Value.IsBsonDateTime && tPro.PropertyType == typeof(DateTime))
                            {
                                if (c.Value.ToUniversalTime().Equals(new DateTime()))
                                {
                                    tPro.SetValue(tObj, c.Value.AsDateTime);
                                }
                                else
                                {
                                    tPro.SetValue(tObj, c.Value.ToLocalTime());
                                }
                                //tPro.SetValue(tObj, c.Value.AsDateTime);
                                break;
                            }
                            else if (c.Value.IsBsonNull)
                            {
                                //tPro.SetValue(tObj, c.Value.asn);
                                break;
                            }
                            else if (c.Value.IsInt32 && tPro.PropertyType == typeof(Int32))
                            {
                                tPro.SetValue(tObj, c.Value.AsInt32);
                                break;
                            }
                            else if (c.Value.IsDouble)
                            {
                                if (tPro.PropertyType == typeof(float))
                                    tPro.SetValue(tObj, (float)c.Value.AsDouble);
                                else if (tPro.PropertyType == typeof(double))
                                    tPro.SetValue(tObj, c.Value.AsDouble);
                                break;
                            }
                            else if (c.Value.IsObjectId && tPro.PropertyType == typeof(ObjectId))
                            {
                                tPro.SetValue(tObj, c.Value.AsObjectId);
                                break;
                            }
                            else if (c.Value.IsInt64 && tPro.PropertyType == typeof(Int64))
                            {
                                tPro.SetValue(tObj, c.Value.AsInt64);
                                break;
                            }
                            else if (c.Value.IsString && tPro.PropertyType == typeof(string))
                            {
                                tPro.SetValue(tObj, c.Value.AsString);
                                break;
                            }
                            else if (c.Value.IsBsonArray)
                            {
                                BsonArray arr = c.Value.AsBsonArray;
                                if (arr.Count != 0)
                                {
                                    //ArrayList[] entityList = new object[arr.Count];
                                    BindingFlags flag = BindingFlags.Instance | BindingFlags.Public;
                                    MethodInfo methodInfo = tPro.PropertyType.GetMethod("Add", flag);
                                    object arrObjs = Activator.CreateInstance(tPro.PropertyType);
                                    int i = 0;
                                    foreach (var o in arr)
                                    {
                                        object arrObj = Activator.CreateInstance(Type.GetType(tPro.PropertyType.GetGenericArguments()[0].FullName));
                                        foreach (var e in o.AsBsonDocument)
                                        {
                                            FillData(e, arrObj, arrObj.GetType().GetProperties());
                                        }
                                        methodInfo.Invoke(arrObjs, new object[] { arrObj });//相当于List<T>调用Add方法
                                    }
                                    tPro.SetValue(tObj, arrObjs);
                                }
                                break;
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                Common.LogHelper.Error("BaseService", ex);
            }
        }


        //术前访视检验数据赋值

        public static Dictionary<string, object> GetJianYanMap(JianYanModel jianyan)
        {
            string blood = "";
            if (jianyan.BloodType != null)
            {
                if (HospitalConfig.Instance.CurrentHospital.HospitalCode.Equals(HospitalConfig.HOSPITAL_CODE_CQ_NTZYY))
                {
                    if (jianyan.BloodType.Contains("阳性"))
                    {

                        jianyan.BloodType = jianyan.BloodType.Replace("阳性（+） ", "Rh+");
                    }
                    else if (jianyan.BloodType.Contains("阴性"))
                    {
                        jianyan.BloodType = jianyan.BloodType.Replace("阴性（-） ", "Rh-");
                    }
                }
                blood = jianyan.BloodType;
            }
            DataManager.Instance.CurrentPatientLink.Patient.Xx = blood;
            Dictionary<string, object> jianYanMap = new Dictionary<string, object>();
            jianYanMap.Add("rbc", jianyan.Rbc);
            jianYanMap.Add("hb", string.IsNullOrEmpty(jianyan.Hb) ? "" : jianyan.Hb);
            jianYanMap.Add("hct", string.IsNullOrEmpty(jianyan.Hct) ? "" : jianyan.Hct);
            jianYanMap.Add("plt", string.IsNullOrEmpty(jianyan.Plt) ? "" : jianyan.Plt);
            jianYanMap.Add("wbc", string.IsNullOrEmpty(jianyan.Wbc) ? "" : jianyan.Wbc);
            jianYanMap.Add("xcg", string.IsNullOrEmpty(jianyan.XueChangGui) ? "" : jianyan.XueChangGui);
            jianYanMap.Add("jiagong", string.IsNullOrEmpty(jianyan.JiaGong) ? "" : jianyan.JiaGong);
            jianYanMap.Add("ncg", string.IsNullOrEmpty(jianyan.NiaoChangGui) ? "" : jianyan.NiaoChangGui);
            jianYanMap.Add("djz", string.IsNullOrEmpty(jianyan.DianJieZhi) ? "" : jianyan.DianJieZhi);
            jianYanMap.Add("ggn", string.IsNullOrEmpty(jianyan.GanGongNeng) ? "" : jianyan.GanGongNeng);
            jianYanMap.Add("sgn", string.IsNullOrEmpty(jianyan.ShenGongNeng) ? "" : jianyan.ShenGongNeng);
            jianYanMap.Add("xuetang", string.IsNullOrEmpty(jianyan.XueTang) ? "" : jianyan.XueTang);
            jianYanMap.Add("thdb", string.IsNullOrEmpty(jianyan.CFanYingDanBai) ? "" : jianyan.CFanYingDanBai);
            jianYanMap.Add("nxgn", string.IsNullOrEmpty(jianyan.NingXueGongNeng) ? "" : jianyan.NingXueGongNeng);
            jianYanMap.Add("ecg", string.IsNullOrEmpty(jianyan.Ecg) ? "" : jianyan.Ecg);
            jianYanMap.Add("xqfx", string.IsNullOrEmpty(jianyan.XueQiFenXi) ? "" : jianyan.XueQiFenXi);
            jianYanMap.Add("fgn", string.IsNullOrEmpty(jianyan.FeiGongNeng) ? "" : jianyan.FeiGongNeng);
            jianYanMap.Add("xp", string.IsNullOrEmpty(jianyan.XiongPian) ? "" : jianyan.XiongPian);
            jianYanMap.Add("qitajy", string.IsNullOrEmpty(jianyan.OtherJianYan) ? "" : jianyan.OtherJianYan);
            jianYanMap.Add("csxdt", string.IsNullOrEmpty(jianyan.ChaoShengXinDongTu) ? "" : jianyan.ChaoShengXinDongTu);

            jianYanMap.Add("hbsag", string.IsNullOrEmpty(jianyan.Hbsag) ? "" : jianyan.Hbsag);
            jianYanMap.Add("hbeag", string.IsNullOrEmpty(jianyan.Hbeag) ? "" : jianyan.Hbeag);
            jianYanMap.Add("hcvab", string.IsNullOrEmpty(jianyan.Hcvab) ? "" : jianyan.Hcvab);
            jianYanMap.Add("hivagab", string.IsNullOrEmpty(jianyan.Hcvagab) ? "" : jianyan.Hcvagab);
            jianYanMap.Add("tpab", string.IsNullOrEmpty(jianyan.Tpab) ? "" : jianyan.Tpab);
            jianYanMap.Add("trust", string.IsNullOrEmpty(jianyan.Trust) ? "" : jianyan.Trust);

            jianYanMap.Add("jg", jianyan.JiaGan);
            jianYanMap.Add("yg", jianyan.YiGan);
            jianYanMap.Add("bg", jianyan.BingGan);
            jianYanMap.Add("khiv", jianyan.KangHIV);
            jianYanMap.Add("md", jianyan.MeiDu);

            //妇幼静脉麻醉单
            jianYanMap.Add("xuecg_test", string.IsNullOrEmpty(jianyan.XueChangGui) ? "" : jianyan.XueChangGui);
            jianYanMap.Add("ningxgn_test", string.IsNullOrEmpty(jianyan.NingXueGongNeng) ? "" : jianyan.NingXueGongNeng);
            jianYanMap.Add("dianjz_test", string.IsNullOrEmpty(jianyan.DianJieZhi) ? "" : jianyan.DianJieZhi);
            jianYanMap.Add("xuet_test", string.IsNullOrEmpty(jianyan.XueTang) ? "" : jianyan.XueTang);

            jianYanMap.Add("gangn_test", string.IsNullOrEmpty(jianyan.GanGongNeng) ? "" : jianyan.GanGongNeng);
            jianYanMap.Add("shengd_test", string.IsNullOrEmpty(jianyan.ShenGongNeng) ? "" : jianyan.ShenGongNeng);
            jianYanMap.Add("ecg_test", string.IsNullOrEmpty(jianyan.Ecg) ? "" : jianyan.Ecg);
            jianYanMap.Add("xiongt_test", string.IsNullOrEmpty(jianyan.XiongPian) ? "" : jianyan.XiongPian);

            //德昌术前访视单
            jianYanMap.Add("pt", string.IsNullOrEmpty(jianyan.PT) ? "" : jianyan.PT);
            jianYanMap.Add("aptt", string.IsNullOrEmpty(jianyan.APTT) ? "" : jianyan.APTT);
            jianYanMap.Add("k", string.IsNullOrEmpty(jianyan.K) ? "" : jianyan.K);
            jianYanMap.Add("alt", string.IsNullOrEmpty(jianyan.ALT) ? "" : jianyan.ALT);
            jianYanMap.Add("urea", string.IsNullOrEmpty(jianyan.Urea) ? "" : jianyan.Urea);
            jianYanMap.Add("crea", string.IsNullOrEmpty(jianyan.Crea) ? "" : jianyan.Crea);
            jianYanMap.Add("glu", string.IsNullOrEmpty(jianyan.GLU) ? "" : jianyan.GLU);


            return jianYanMap;
        }
        public static PatientLisDataModel GetLisData()
        {
            PatientLinkModel patientLink = DataManager.Instance.CurrentPatientLink;
            if (patientLink.Patient.Zyh == null || "".Equals(patientLink.Patient.Zyh))
            {
                return null;
            }
            PatientLisDataModel PatientLisData = PatientLisDataService.Instance.GetPatientDrugs8PatientID(patientLink.Id.ToString());
            if (PatientLisData == null)
            {
                return null;
            }

            return PatientLisData;
        }

        public static string GetAnesID()
        {
            StringBuilder mzdh = new StringBuilder();
            int year = DateTime.Now.Year;
            mzdh.Append(year);
            long count = PatientLinkService.Instance.FindAnesID();
            if (count < 1000) mzdh.Append(0);
            else if (count < 100) mzdh.Append(00);
            else if (count < 10) mzdh.Append(000);
            mzdh.Append(count);
            return mzdh.ToString();
        }

        public static string CheckAccount(string nameStr, string role)
        {
            if (nameStr == null || "".Equals(nameStr)) return "";
            AccountModel account = null;
            if (!string.IsNullOrEmpty(nameStr) && nameStr.Length == 24)
            {
                return nameStr.ToString();
            }
            else
            {
                try
                {
                    account = AccountListCtrlViewModel.Instance.AccountList.Find(O => O.TrueName.Equals(nameStr));
                }
                catch (Exception)
                {
                }
                if (account == null)
                {
                    if (MessageBoxCommon.ShowDialog("系统不存在:" + nameStr + " 的用户，是否新建", MessageBoxCommon.OKCANCLE).Value == true)
                    {
                        AccountModel a = AddNewAccount(nameStr, role);
                        AccountListCtrlViewModel.Instance.AccountList.Add(a);
                        nameStr = a.Id.ToString();
                    }
                }
                else
                {
                    nameStr = account.Id.ToString();
                }
            }
            return nameStr.ToString();
        }
        public static AccountModel AddNewAccount(string name, string role)
        {
            AccountModel accout = new AccountModel();
            accout.TrueName = name;
            accout.LoginName = name.GetSpellCode().ToLower();
            accout.Pwd = name.MD5Encrypt32();
            accout.WorkID = accout.LoginName;
            accout.Role = role;
            accout.Title = role;
            accout.ZhiCheng = role;
            accout.CanLogin = false;
            accout.TrueName = name;
            accout.Gender = "男";
            if (role.Equals("麻醉医生"))
            {
                accout.OfficeID = "12125";
            }
            else if (role.Equals("手术医生"))
            {
                accout.OfficeID = "12123";
            }
            else
            {
                accout.OfficeID = "12124";
            }
            accout.OfficeName = role.Equals("麻醉医生") ? "麻醉科" : "手术室";
            accout.Status = Constants.FLAG_VALID;
            accout.SchoolLevel = "本科";
            accout.InDate = DateTime.Now;
            accout.CreateTime = DateTime.Now;
            accout.LastUpdateTime = DateTime.Now;
            AccountService.Instance.Update(accout);
            AccountListCtrlViewModel.Instance.AccountList.Add(accout);
            return accout;
        }

        public static StatisticsPatientLinkModel ConversionPatientLink(this PatientLinkModel p)
        {
            StatisticsPatientLinkModel sp = new StatisticsPatientLinkModel();
            sp.Id = p.Id.ToString();
            sp.Brxm = p.Patient.Brxm;
            sp.Zyh = p.Patient.Zyh;
            sp.Xb = p.Patient.Xb;
            sp.Nl = p.Patient.Nl;
            sp.Zych = p.Patient.Zych;
            sp.Ksmc = p.Patient.Ksmc;
            sp.Ssj = p.Schedule.Pbssjh;
            sp.Ssrq = p.Status.InRoomTime;
            sp.Sszd = p.AnesthesiaRecord.Shzd1;
            sp.Ssmc = p.AnesthesiaRecord.Ysss1;
            sp.Ssys = p.AnesthesiaRecord.OperDoctor1;
            sp.Zmys = p.AnesthesiaRecord.Zmys;
            sp.Fmys = p.AnesthesiaRecord.Fmys1;
            sp.Mzfs = p.AnesthesiaRecord.Mzff;
            sp.Xshs = p.AnesthesiaRecord.Xshs1;
            sp.Xhhs = p.AnesthesiaRecord.Xhhs1;
            sp.Tsqk = p.AnesthesiaRecord.Tsqk;

            sp.InRoomTime = p.Status.InRoomTime;
            sp.MazuiStartTime = p.Status.MazuiStartTime;
            sp.OperStartTime = p.Status.OperStartTime;
            sp.OperEndTime = p.Status.OperEndTime;
            sp.MazuiEndTime = p.Status.MazuiEndTime;
            sp.OutRoomTime = p.Status.OutRoomTime;
            sp.MazuiSpanTime = p.Status.MazuiSpanTime.ToString();
            sp.OperSpanTime = p.Status.OperSpanTime.ToString();
            sp.Mzks_ssks_span = getTimeSpan(p.Status.MazuiStartTime, p.Status.OperStartTime);
            sp.Ssjs_mzjs_span = getTimeSpan(p.Status.OperEndTime, p.Status.MazuiEndTime);
            sp.Rsss_mzks_span = getTimeSpan(p.Status.InRoomTime, p.Status.MazuiStartTime);
            sp.Mzjs_csss_span = getTimeSpan(p.Status.MazuiEndTime, p.Status.OutRoomTime);
            if (HospitalConfig.Instance.CurrentHospital.HospitalCode.Equals(HospitalConfig.HOSPITAL_CODE_CQ_NTZYY))
            {
                sp.Fssj = p.ScreenFssj();
                sp.Ztpf = p.ScreenZtpf();
                sp.Zjpf = p.ScreenZjpf();
                sp.Dxyz = p.ScreenDxyz();
                sp.Ex = p.ScreenEx();
                sp.Ot = p.ScreenOt();
                sp.Sy = p.ScreenSy();
                sp.Nzl = p.ScreenNzl();
                sp.Ydza = p.ScreenYdza();
                sp.Gjza = p.ScreenGjza();
                sp.Pca = p.ScreenPCA();
            }

            return sp;
        }

        public static string getTimeSpan(DateTime d1, DateTime d2)
        {
            long spanTime = 0;
            TimeSpan span = d2 - d1;
            long Minutes = span.Days * 24 * 60 + span.Hours * 60 + span.Minutes;
            if (Minutes > 0)
            {
                spanTime = Minutes;
            }
            return spanTime.ToString();
        }


        // 通过生日和当前日期计算岁，月，天

        //public static void Test()
        //{
        //    Date dobDate = parseDateBirthDay(patItemType.getDATEOFBIRTH());
        //    patientLink.getPatient().setDob(dobDate);
        //    String ageStr = MyUtility.getAge(dobDate, patientLink.getApplication().getSssqsj());
        //    if (!"".equals(ageStr))
        //    {
        //        boolean isContainUnit = false;
        //        for (String unit : this.ageUnit)
        //        {
        //            if (ageStr.contains(unit))
        //            {
        //                patientLink.getPatient().setNl(ageStr);
        //                patientLink.getPatient().setNldw(unit);
        //                int indexUnit = ageStr.indexOf(unit);
        //                try
        //                {
        //                    Integer numAge = Integer.valueOf(Integer.parseInt(ageStr.substring(0, indexUnit)));
        //                    patientLink.getPatient().setNumAge(numAge);
        //                }
        //                catch (Exception e)
        //                {
        //                }
        //                isContainUnit = true;
        //                break;
        //            }
        //        }
        //        if (!isContainUnit)
        //        {
        //            patientLink.getPatient().setNl(ageStr + Constants.AGE_UNIT_YEAR);
        //            patientLink.getPatient().setNldw(Constants.AGE_UNIT_YEAR);
        //            try
        //            {
        //                Integer numAge = Integer.valueOf(Integer.parseInt(ageStr));
        //                patientLink.getPatient().setNumAge(numAge);
        //            }
        //            catch (Exception e)
        //            {
        //            }
        //        }
        //    }
        //}



        /// </summary>

        /// <param name="birthday">生日</param>

        /// <param name="now">当前日期</param>

        /// <param name="year">岁</param>

        /// <param name="month">月</param>

        /// <param name="day">天</param>

        public static void GetAgeByBirthday(DateTime birthday, out int year, out int month, out int day)
        {
            DateTime now = DateTime.Now;

            //生日的年，月，日
            int birthdayYear = birthday.Year;
            int birthdayMonth = birthday.Month;
            int birthdayDay = birthday.Day;

            //当前时间的年,月,日
            int nowYear = now.Year;
            int nowMonth = now.Month;
            int nowDay = now.Day;

            //得到天
            if (nowDay >= birthdayDay)
            {
                day = nowDay - birthdayDay;
            }
            else
            {
                nowMonth -= 1;
                day = GetDay(nowMonth, nowYear) + nowDay - birthdayDay;
            }

            //得到月
            if (nowMonth >= birthdayMonth)
            {
                month = nowMonth - birthdayMonth;
            }
            else
            {
                nowYear -= 1;
                month = 12 + nowMonth - birthdayMonth;
            }
            //得到年
            year = nowYear - birthdayYear;
        }

        /// <summary>
        /// 获取天数
        /// </summary>

        private static int GetDay(int month, int year)
        {
            int day = 0;
            switch (month)
            {
                case 0:
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    day = 31;
                    break;

                case 2:
                    //闰年天，平年天
                    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
                    {
                        day = 29;
                    }
                    else
                    {
                        day = 28;
                    }
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    day = 30;
                    break;
            }
            return day;
        }

        #endregion

        #region EventHandlers

        #endregion

    }
}
